class WebSocketService {
    constructor(url) {
        this.url = url
        this.socket = null
        this.listeners = {}
        this.reconnectAttempts = 0
        this.maxReconnectAttempts = 5
        this.reconnectInterval = 3000 // 3秒
    }

    connect(url) {
        if (url) {
            this.url = url;
        }
        this.socket = new WebSocket(this.url)

        this.socket.onopen = () => {
            console.log('WebSocket connected')
            this.reconnectAttempts = 0
            this.emit('connected')
        }

        this.socket.onmessage = (event) => {
            try {
                const data = JSON.parse(event.data)
                let eventName = data.eventName || null;
                if (eventName != null) {
                    this.emit(eventName, data)
                } else {
                    this.emit('message', data)
                }
            } catch (error) {
                console.error('Error parsing message:', error)
            }
        }

        this.socket.onclose = () => {
            console.log('WebSocket disconnected')
            this.emit('disconnected')
            this._attemptReconnect()
        }

        this.socket.onerror = (error) => {
            console.error('WebSocket error:', error)
            this.emit('error', error)
        }
        return this;
    }

    _attemptReconnect() {
        if (this.reconnectAttempts < this.maxReconnectAttempts) {
            this.reconnectAttempts++
            console.log(`Attempting to reconnect (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`)
            setTimeout(() => this.connect(), this.reconnectInterval)
        } else {
            console.log('Max reconnection attempts reached')
        }
    }

    send(data) {
        if (this.socket && this.socket.readyState === WebSocket.OPEN) {
            this.socket.send(JSON.stringify(data))
        } else {
            console.warn('WebSocket is not connected')
        }
    }

    /**
     *
     * @param event 事件名称
     * @param callback 回调函数
     *
     */
    on(event, callback) {
        if (!this.listeners[event]) {
            this.listeners[event] = []
        }
        this.listeners[event].push(callback)
        return this;
    }

    off(event, callback) {
        if (this.listeners[event]) {
            this.listeners[event] = this.listeners[event].filter(
                (listener) => listener !== callback
            )
        }
    }

    emit(event, ...args) {
        if (this.listeners[event]) {
            this.listeners[event].forEach((callback) => callback(...args))
        }
    }

    disconnect() {
        if (this.socket) {
            this.socket.close()
        }
    }
}

export default new WebSocketService('ws:127.0.0.1:8765')